function div(a, b)
{
	return Math.floor(a/b);
}

function HolidayToString()
{
	return this.description;
}

function Holiday(day,month,condition,description,type)
{
	this.day = day;
	this.month = month;
	this.condition = condition;
	this.description = description;
	this.holiday_type = type ? type : 'holiday';
	this.toString = HolidayToString;
}

function CheckHanuka(gg)
{
	var g = new Date;
	g.setYear(gg.getFullYear());
	g.setMonth(gg.getMonth());
	g.setDate(gg.getDate()-3);
	var h = new HebrewDate;
	h.convertGregorian(g);
	return (h.hd_day==28);
}

var HOUR = 1080;
var DAY  =(24*HOUR);
var WEEK =(7*DAY);
function M(h,p)
{
	return((h)*HOUR+p);
}
var MONTH =(DAY+M(12,793));

function dysiz(y)
{
	var m, nm, dw, s, l;
	l = y*7+1;
	m = y*12+ div(l,19);
	l %= 19;
	nm = m*MONTH+M(1+6,779);
	s = m*28+div(nm,DAY)-2;

	nm %= WEEK;
	dw = div(nm,DAY);
	nm %= DAY;

	if(l < 12 && dw==3 && nm>=M(9+6,204) || l < 7 && dw==2 && nm>=M(15+6,589))
		s++,dw++;
	if(dw == 1 || dw == 4 || dw == 6)
		s++;
	return s;
}

function hdate(d, m, y)
{
	var h = new HebrewDate;
	var s;

	if((m -= 2) <= 0)
	{
		m += 12;
		y--;
	}
	d +=(365*y) + div(y,4) + div(367*m,12) + 5968;
	d -= div(y,100)-div(y,400)-2;
	h.hd_dw =(d+1)%7;

	y += 16;
	s = dysiz(y);
	m = dysiz(y+1);
	while(d >= m)
	{
		s = m;
		y++;
		m = dysiz(y+1);
	}
	d -= s;
	s = m-s;
	y += 3744;

	h.hd_flg = s%10-4;

	if(d >= s-236)
	{
		d -= s-236;
		m = div(d*2,59);
		d -= div((m*59+1),2);
		m += 4;
		if(s>365 && m<=5)
			m += 8;
	}
	else
	{
		s = 114+s%10;
		m = div(d*4,s);
		d -= div((m*s+3),4);
	}

	h.hd_day = d;
	h.hd_mon = m;
	h.hd_year = y;
	h.hd_leap =(s > 365);
	return h;
}

function HDHoliday()
{
	var dow = this.hd_dw + 1;
	var year = this.gregorian.getFullYear();
	var g = this.gregorian;

	var sSummer = '';

	var i;
	for(i = 0; i < Holidays.length; i++)
	{
		if(Holidays[i].month == this.hd_mon+1 && Holidays[i].day == this.hd_day+1 && eval(Holidays[i].condition))
		{
			if(sSummer)
				Holidays[i].description += sSummer;
			return Holidays[i];
		}
	}
	return sSummer;
}

function HDToString()
{
	var s = this.format;
	s = s.replace('DD', Gimatria(this.hd_day+1));
	s = s.replace('MM', months[this.hd_mon]);
	s = s.replace('YYYY', Gimatria(this.hd_year));
	return s;
}

function HDGtoH(d)
{
	var h = hdate(d.getDate(), d.getMonth()+1, d.getFullYear());
	this.hd_day = h.hd_day;
	this.hd_mon = h.hd_mon;
	this.hd_year = h.hd_year;
	this.hd_leap = h.hd_leap;
	this.hd_dw = h.hd_dw;
	this.hd_flg = h.hd_flg;
	this.gregorian = d;
}

function HDSetDate(n)
{
	this.gregorian.setDate(n +(this.gregorian.getDate() - this.hd_day));
	this.convertGregorian(this.gregorian);
}

function HebrewDate()
{
	this.hd_day = 0;
	this.hd_mon = 0;
	this.hd_year = 0;
	this.hd_leap = 0;
	this.hd_dw = 0;
	this.hd_flg = 0;
	this.format = 'DD MM YYYY';
	this.toString = HDToString;
	this.convertGregorian = HDGtoH;
	this.getHoliday = HDHoliday;
	this.gregorian = new Date();
	this.setDate = HDSetDate;
}

function DisplayHoliday(h)
{
	if(!h)
		return '';
	return '<br><span class="' + h.holiday_type + '">' + h + '</span>';
	return '';
}

function calendar_Start(curMonth, curYear, curError, holidayColor, saddayColor, sabbathColor, upperColor)
{
	var html='';
	var h = new HebrewDate;
	Date.prototype.toString = function()
	{
		return 'D' + this.getFullYear()+'-'+this.getMonth()+'-'+this.getDate();
	}
	var d = new Date;
	h.convertGregorian(d);
	html+=h + '<br>';
	html+=(d.getDate() < 10 ? '0' : '');
	html+=d.getDate() + '.';
	html+=(d.getMonth() < 10 ? '0' : '');
	html+=(d.getMonth() + 1) + '.';
	html+=d.getFullYear();
	document.getElementById('calendar_caption').innerHTML=html;
	document.getElementById('clock_caption').innerHTML=weekdays[d.getDay()];
	var holiday = h.getHoliday();
	if(holiday)
		document.getElementById('clock_caption').innerHTML += '<br>' + holiday;
	
	if(curYear<100)
		alert(curError);
	d.setDate(1);
	d.setMonth(curMonth-1);
	d.setYear(curYear);
	h.format = 'MM - ';
	h.convertGregorian(d);
	var nFirstHebrewMonth = h.hd_mon;
	var sFirstHebrewMonth = h.toString();
	h.format = 'MM YYYY';
	d.setMonth(curMonth);
	d = new Date(d.getTime() - 24*60*60*1000);
	h.convertGregorian(d);
	d.setDate(1);
	d.setMonth(curMonth-1);
	var row = 1;
	h.format = 'DD MM';
	
	for(var col=0;col<7;col++)
	{
			try
			{
				document.getElementById('calendar_table').rows[0].cells[col].style.backgroundColor = upperColor;
			}
			catch(ex)
			{
			}
	}
	
	while(d.getMonth()==curMonth-1)
	{
		h.convertGregorian(d);
		try
		{
			document.getElementById('calendar_table').rows[row].cells[d.getDay()].title = h;
			document.getElementById('calendar_table').rows[row].cells[d.getDay()].innerHTML = d.getDate();
			if(d.getDay()==6)
				document.getElementById('calendar_table').rows[row].cells[d.getDay()].style.backgroundColor = sabbathColor;
			if(h.hd_day==0)
			{
				document.getElementById('calendar_table').rows[row].cells[d.getDay()].style.backgroundColor = holidayColor;
			}
			holiday = h.getHoliday();
			if(holiday)
			{
				if(holiday.holiday_type=='yomtov' || holiday.holiday_type=='holiday')
					document.getElementById('calendar_table').rows[row].cells[d.getDay()].style.backgroundColor = holidayColor;
				else
					document.getElementById('calendar_table').rows[row].cells[d.getDay()].style.backgroundColor = saddayColor;
				document.getElementById('calendar_table').rows[row].cells[d.getDay()].title = h.getHoliday() + ', ' + h;
			}
		}
		catch(ex)
		{
		}
		if(d.getDay() == 6)
			row++;
		d.setDate(d.getDate()+1);
	}
}
